import { defineComponent, computed, ref, reactive, watchEffect, createVNode } from 'vue';
import { createUniqueId } from '../use/createUniqueId.js';

const index = /* @__PURE__ */ defineComponent({
  name: "IndexList",
  props: {
    data: {
      type: Array
    },
    selectable: {
      type: Boolean,
      default: false
    },
    promote: {
      type: Boolean,
      default: true
    },
    border: {
      type: Boolean,
      default: false
    },
    modelValue: {
      type: Array,
      default: () => []
    },
    renderItem: {
      type: Function
    }
  },
  emits: ['change'],
  setup(props, {
    emit
  }) {
    const promote = computed(() => props.promote ?? true);
    const value = ref(props.modelValue ?? []);
    const activeAnchor = ref('');
    const showPromote = ref(false);
    const promoteText = ref('');
    const store = reactive({
      list: [],
      listMap: {}
    });

    // 构建数据结构
    let map = {};
    const wrap = ref(null);
    const topMap = {};
    watchEffect(() => {
      const list = [];
      map = {};
      const listMap = {};
      props.data.forEach(item => {
        if (item.id === undefined || item.id === null) {
          item.id = createUniqueId();
        }
        const newItem = {
          id: item.id
        };
        map[item.id] = item;
        listMap[item.id] = newItem;
        list.push(newItem);
        if (item.children) {
          newItem.children = [];
          item.children.forEach(subItem => {
            if (subItem.id === undefined || subItem.id === null) {
              subItem.id = createUniqueId();
            }
            map[subItem.id] = subItem;
            const newSubItem = {
              id: subItem.id
            };
            listMap[subItem.id] = newSubItem;
            newItem.children.push(newSubItem);
          });
        }
      });
      store.list = list;
      store.listMap = listMap;
    });
    const classList = computed(() => ({
      'cm-index-list': true,
      'cm-index-list-border': props.border
    }));
    const onItemClick = subItem => {
      if (!props.selectable) {
        return;
      }
      const val = value.value;
      const id = subItem.id;
      if (subItem.active) {
        const index = val.indexOf(id);
        val.splice(index, 1);
        value.value = val;
      } else {
        val.push(id);
        value.value = [...val];
      }
      emit('change', value.value);
      store.listMap[subItem.id].active = !subItem.active;
    };
    let promoteTimer = null;
    const gotoAnchor = (id, name, e) => {
      if (e.preventDefault) {
        e.preventDefault();
      }
      if (e.stopPropagation) {
        e.stopPropagation();
      }
      const ele = document.querySelector(id);
      if (ele) {
        if (promote.value) {
          promoteText.value = name;
          showPromote.value = true;
          if (promoteTimer) {
            clearTimeout(promoteTimer);
          }
          promoteTimer = setTimeout(() => {
            scrollEnd();
          }, 1000);
        }
        const eleOff = ele.getBoundingClientRect().top;
        const parentOff = wrap.value.getBoundingClientRect().top;
        const scrollTop = eleOff - parentOff;
        wrap.value.scrollTo({
          top: wrap.value.scrollTop + scrollTop,
          behavior: "smooth"
        });
      }
    };
    const scrollEnd = () => {
      showPromote.value = false;
    };
    const handleScroll = () => {
      const scrollTop = wrap.value.scrollTop;
      const id = getAnchorByScrollTop(scrollTop);
      activeAnchor.value = id;
    };
    const getAnchorByScrollTop = scrollTop => {
      let minId = '';
      let min = Number.MAX_VALUE;
      for (const id in topMap) {
        const t = Math.abs(topMap[id] - scrollTop);
        if (min > t) {
          min = t;
          minId = id;
        }
      }
      return minId;
    };
    const initTop = (e, id) => {
      queueMicrotask(() => {
        topMap[id] = e && e.offsetTop;
      });
    };
    const promoteClass = () => ({
      'cm-index-list-promote': true,
      'cm-index-list-promote-show': showPromote.value
    });
    return () => createVNode("div", {
      "class": classList.value
    }, [createVNode("div", {
      "class": "cm-index-list-list",
      "ref": wrap,
      "onScroll": handleScroll
    }, [store.list.map(item => {
      const dataItem = map[item.id];
      return createVNode("dl", {
        "id": `cm_index_list_${item.id}`,
        "ref": e => {
          initTop(e, item.id);
        }
      }, [createVNode("dt", null, [dataItem.name]), item.children && item.children.map(subItem => {
        const subDataItem = map[subItem.id];
        return createVNode("dd", {
          "class": subItem.active ? 'active' : '',
          "onClick": onItemClick.bind(null, subItem)
        }, [props.renderItem ? props.renderItem(subDataItem, subItem.active) : subDataItem.name]);
      })]);
    })]), createVNode("div", {
      "class": "cm-index-list-nav"
    }, [store.list.map(item => {
      const dataItem = map[item.id];
      const active = () => activeAnchor.value === item.id;
      const classList = () => ({
        'cm-index-list-nav-item': true,
        'active': active()
      });
      return createVNode("div", {
        "class": classList(),
        "onClick": gotoAnchor.bind(null, `#cm_index_list_${item.id}`, dataItem.id)
      }, [dataItem.id]);
    })]), promote.value ? createVNode("div", {
      "class": promoteClass()
    }, [promoteText.value]) : null]);
  }
});

export { index as default };
